﻿using Artech.Common;
using Artech.Common.Properties;
using Artech.Core.Resources.Configuration;
using Microsoft.Practices.Unity.Utility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;

namespace Artech.Core.Resources
{
    public class ResourceManager
    {
        private IResourceProvider provider;
        private static ResourceManager current;
        private ResourceManager()
        {
            this.Providers = new ServiceLocatableObjectCollection<IResourceProvider>(ResourcesSettings.GetSettings().ServiceLocator);
        }
        public static ResourceManager Current
        {
            get { return current ?? (current = new ResourceManager()); }
        }

        public IResourceProvider Provider
        {
            get { return provider ?? (provider = ResourcesSettings.GetSettings().ServiceLocator.GetService<IResourceProvider>()); }
        }

        public ServiceLocatableObjectCollection<IResourceProvider> Providers { get; private set; }

        public string GetString(string category, string name, CultureInfo culture)
        {
            string value;
            if (this.TryGetString(category, name, culture, out value))
            {
                return value;
            }
            throw new IndexOutOfRangeException(ResourceUtility.Format(CoreResources.ExceptionStringResourceNotExists, name, category));
        }

        public bool TryGetString(string category, string name, out string value)
        {
            return this.Provider.TryGetString(category, name, CultureInfo.CurrentUICulture, out value);
        }

        public bool TryGetString(string category, string name, CultureInfo culture, out string value)
        {
            Guard.ArgumentNotNullOrEmpty(category, "category");
            Guard.ArgumentNotNullOrEmpty(name, "name");
            return this.Provider.TryGetString(category, name, culture, out value);
        }

        public IEnumerable<StringResourceEntry> GetStringsForEdit(StringResourceSearchCriteria criteria, int pageSize, int pageIndex, ResourceEntryField sortField, SortDirection sortDirection)
        {
            Guard.ArgumentNotNull(criteria, "criteria");
            Guard2.ArgumentIsValidePageSize(pageSize, "pageSize");
            Guard2.ArgumentIsValidePageIndex(pageIndex, "pageIndex");

            return this.Provider.GetStringsForEdit(criteria, pageSize, pageIndex, sortField, sortDirection);
        }

        public void UpdateStrings(StatefulEntryCollection<StringResourceEntry> resourceEntries)
        {
            Guard.ArgumentNotNull(resourceEntries, "resourceEntries");
            this.Provider.UpdateStrings(resourceEntries);
        }
    }
}